package com.example.demo.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.config.ZhipuAIConfig;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class ZhipuAIService {

    @Autowired
    private ZhipuAIConfig config;
    
    private final OkHttpClient client = new OkHttpClient.Builder()
        .connectTimeout(60, TimeUnit.SECONDS)    // 连接超时时间增加到60秒
        .writeTimeout(60, TimeUnit.SECONDS)      // 写入超时时间增加到60秒
        .readTimeout(300, TimeUnit.SECONDS)      // 读取超时时间增加到300秒（5分钟）
        .build();

    /**
     * 生成JWT
     */
    private String generateJWT() {
        long timestamp = System.currentTimeMillis() / 1000;
        long expiration = timestamp + 3600; // 1小时后过期

        // 1. 生成Header
        Map<String, String> header = new HashMap<>();
        header.put("alg", "HS256");
        header.put("sign_type", "SIGN");
        String headerStr = Base64.encodeBase64URLSafeString(JSON.toJSONString(header).getBytes(StandardCharsets.UTF_8));

        // 2. 生成Payload
        Map<String, Object> payload = new HashMap<>();
        payload.put("api_key", config.getApiKey());
        payload.put("exp", expiration);
        payload.put("timestamp", timestamp);
        String payloadStr = Base64.encodeBase64URLSafeString(JSON.toJSONString(payload).getBytes(StandardCharsets.UTF_8));

        // 3. 生成Signature
        try {
            String signatureRaw = headerStr + "." + payloadStr;
            Mac hmacSha256 = Mac.getInstance("HmacSHA256");
            SecretKeySpec secretKey = new SecretKeySpec(
                config.getApiSecret().getBytes(StandardCharsets.UTF_8),
                "HmacSHA256"
            );
            hmacSha256.init(secretKey);
            byte[] signatureBytes = hmacSha256.doFinal(signatureRaw.getBytes(StandardCharsets.UTF_8));
            String signature = Base64.encodeBase64URLSafeString(signatureBytes);

            // 4. 组装JWT
            return headerStr + "." + payloadStr + "." + signature;
        } catch (Exception e) {
            log.error("生成JWT失败", e);
            throw new RuntimeException("生成JWT失败", e);
        }
    }

    /**
     * 调用智谱AI API
     */
    private String callZhipuAPI(String prompt) throws IOException {
        String jwt = generateJWT();
        
        // 构建请求体
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("model", config.getModel());
        requestBody.put("messages", List.of(
            Map.of(
                "role", "user",
                "content", prompt
            )
        ));
        requestBody.put("temperature", 0.7);
        requestBody.put("top_p", 0.7);
        
        // 构建请求
        Request request = new Request.Builder()
            .url(config.getEndpoint())
            .post(RequestBody.create(
                JSON.toJSONString(requestBody),
                MediaType.parse("application/json")
            ))
            .addHeader("Content-Type", "application/json")
            .addHeader("Authorization", "Bearer " + jwt)
            .build();
            
        log.info("API请求信息: url={}, jwt={}, requestBody={}", 
            request.url(), jwt, JSON.toJSONString(requestBody));
            
        // 发送请求
        try (Response response = client.newCall(request).execute()) {
            String responseBody = response.body().string();
            log.info("API响应数据: {}", responseBody);
            
            if (!response.isSuccessful()) {
                log.error("API请求失败: code={}, body={}", response.code(), responseBody);
                throw new RuntimeException("API请求失败: " + responseBody);
            }
            
            JSONObject jsonResponse = JSON.parseObject(responseBody);
            if (!jsonResponse.containsKey("choices") || jsonResponse.getJSONArray("choices").isEmpty()) {
                throw new RuntimeException("API返回数据格式错误: " + responseBody);
            }
            
            return jsonResponse.getJSONArray("choices")
                .getJSONObject(0)
                .getJSONObject("message")
                .getString("content");
        }
    }

    /**
     * 生成测评问题
     */
    public String generateQuestion(List<Map<String, String>> previousQA) {
        String context;
        if (previousQA == null || previousQA.isEmpty()) {
            context = "这是第一个问题";
        } else {
            context = previousQA.stream()
                .map(qa -> String.format("问：%s\n答：%s", qa.get("question"), qa.get("answer")))
                .reduce((a, b) -> a + "\n" + b)
                .orElse("");
        }
        
        String prompt = config.getQuestionPrompt().replace("{context}", context);
        
        try {
            String question = callZhipuAPI(prompt);
            // 包装成前端期望的格式
            return JSON.toJSONString(Map.of(
                "question", question
            ));
        } catch (IOException e) {
            log.error("生成问题失败", e);
            throw new RuntimeException("生成问题失败", e);
        }
    }

    /**
     * 生成分析报告
     */
    public String generateAnalysis(List<Map<String, String>> qaRecords) {
        String recordsText = qaRecords.stream()
            .map(qa -> String.format("问：%s\n答：%s", qa.get("question"), qa.get("answer")))
            .reduce((a, b) -> a + "\n" + b)
            .orElse("");
            
        String prompt = config.getAnalysisPrompt().replace("{qa_records}", recordsText);
        
        try {
            String response = callZhipuAPI(prompt);
            Map<String, Object> result = parseAnalysisResponse(response);
            // 直接返回JSON字符串，让Controller处理包装
            return JSON.toJSONString(result);
        } catch (IOException e) {
            log.error("生成分析报告失败", e);
            throw new RuntimeException("生成分析报告失败", e);
        }
    }
    
    /**
     * 解析分析报告响应
     */
    private Map<String, Object> parseAnalysisResponse(String response) {
        String[] sections = response.split("\n\n");
        String summary = sections[0];
        List<Map<String, String>> aspects = new ArrayList<>();
        List<String> suggestions = new ArrayList<>();
        
        String currentSection = "";
        for (String section : sections) {
            if (section.contains("具体表现分析")) {
                currentSection = "aspects";
            } else if (section.contains("针对性建议")) {
                currentSection = "suggestions";
            } else if (currentSection.equals("aspects") && !section.trim().isEmpty()) {
                String[] parts = section.split("：", 2);
                if (parts.length == 2) {
                    aspects.add(Map.of(
                        "title", parts[0].trim(),
                        "content", parts[1].trim()
                    ));
                }
            } else if (currentSection.equals("suggestions") && !section.trim().isEmpty()) {
                suggestions.add(section.trim());
            }
        }
        
        return Map.of(
            "summary", summary,
            "aspects", aspects,
            "suggestions", suggestions.isEmpty() ? List.of("暂无具体建议") : suggestions
        );
    }

    /**
     * 生成PDF报告文件
     */
    public byte[] generateReportFile(Map<String, Object> reportData) throws DocumentException, IOException {
        Document document = new Document(PageSize.A4);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        
        try {
            PdfWriter.getInstance(document, outputStream);
            document.open();
            
            // 设置中文字体
            BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            Font titleFont = new Font(baseFont, 18, Font.BOLD);
            Font headingFont = new Font(baseFont, 14, Font.BOLD);
            Font normalFont = new Font(baseFont, 12, Font.NORMAL);
            
            // 添加标题
            Paragraph title = new Paragraph("儿童心理测评报告", titleFont);
            title.setAlignment(Element.ALIGN_CENTER);
            title.setSpacingAfter(20);
            document.add(title);
            
            // 添加时间
            Paragraph date = new Paragraph("生成时间：" + new Date().toString(), normalFont);
            date.setSpacingAfter(20);
            document.add(date);
            
            // 添加总结
            document.add(new Paragraph("测评总结", headingFont));
            document.add(new Paragraph(reportData.get("summary").toString(), normalFont));
            document.add(Chunk.NEWLINE);
            
            // 添加具体表现分析
            document.add(new Paragraph("具体表现分析", headingFont));
            @SuppressWarnings("unchecked")
            List<Map<String, String>> aspects = (List<Map<String, String>>) reportData.get("aspects");
            for (Map<String, String> aspect : aspects) {
                Paragraph aspectTitle = new Paragraph(aspect.get("title"), new Font(baseFont, 12, Font.BOLD));
                document.add(aspectTitle);
                document.add(new Paragraph(aspect.get("content"), normalFont));
                document.add(Chunk.NEWLINE);
            }
            
            // 添加建议
            document.add(new Paragraph("针对性建议", headingFont));
            @SuppressWarnings("unchecked")
            List<String> suggestions = (List<String>) reportData.get("suggestions");
            for (String suggestion : suggestions) {
                document.add(new Paragraph("• " + suggestion, normalFont));
            }
            
            return outputStream.toByteArray();
        } finally {
            document.close();
            outputStream.close();
        }
    }
} 